<?php
/**
 * +--------------------------------------------------------+
 * @Created by Phpstorm.
 * @Category CollectService.php
 * @Depiction 采集业务
 * @Author hwy
 * @Date 2021/2/14  20:17
 * +--------------------------------------------------------+
 */


namespace App\Services;

use App\Jobs\CollectArticleJob;
use App\Models\CollectArticle;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
use QL\QueryList;

class CollectService extends BaseService
{
    protected $stock;

    public function __construct()
    {
        $this->stock = '';
    }

    /**
     * @param string $url 路径
     * @param array $reg 规则
     * @param string $rang 范围
     * @return array
     * @Depiction QueryList 获取数据-通用方法
     * @Author hwy
     * @Date 2021/4/20  15:01
     */
    public function collect(string $url, array $reg, string $rang)
    {
        try {
            $ql = QueryList::get($url)->rules($reg)->range($rang)->query();

            $data = $ql->getData();
            $data = $data->all();
        } catch (Exception $exception) {
            $data = [];
        }

        return $data;
    }

    /**
     * @param $data
     * @param $site_url
     * @param int $type
     * @return bool
     * @Depiction 采集数据处理后，存入redis
     * @Author hwy
     * @Date 2021/4/20  15:00
     */
    public function collect_redis_set($data, $site_url, $type = 1)
    {
        $time = Carbon::now()->toDateTimeString();

        $cache_name = 'collect_article';
        //todo 获取缓存数据，判断是否重复
        $collect_data_title = CollectArticle::query()->select('title')
            ->where('created_at', '>', Carbon::today()->subDays(30))
            ->get()
            ->pluck('title')
            ->toArray();

        foreach ($data as $value) {
            $title = explode('  ', $value['title'])[0] ?? $value['title'];
            if (!in_array($title, $collect_data_title)) {
                //todo 假设不在30天内的数据，再去数据库查询是否存在，暂时不需要，先注释。请求数据库的量还是挺大
                //                $count = CollectArticle::select('title')->where('title', $value['title'])->first();
                //                if ($count) {
                //                    continue;
                //                }
                $insert = [
                    'title'      => $title,
                    'href'       => $site_url . $value['href'],
                    'source'     => $type,
                    'created_at' => $time,
                    'updated_at' => $time,
                ];
                Redis::rpush($cache_name, json_encode($insert));
            }
        }

        return true;
    }

    /**
     * @return array
     * @Depiction 文章采集-redis中取出，一次性添加到数据库
     * @Author hwy
     * @Date 2021/4/20  14:59
     */
    public function addDataDb()
    {
        $cache_name  = 'collect_article';
        $data_len    = Redis::llen($cache_name);
        $insert_data = [];
        $i           = 1;
        while ($i <= $data_len) {
            $insert_datas          = json_decode(Redis::lPop($cache_name), true);
            $insert_datas['title'] = explode('  ', $insert_datas['title'])[0] ?? $insert_datas['title'];
            $insert_data[]         = $insert_datas;
            $i++;
        }

        if (!empty($insert_data)) {
            //缓存数据去重
            $insert_data = uniqu_arr($insert_data);
            try {
                dispatch((new CollectArticleJob($insert_data))->onQueue('default'));
                //采集数量发送钉钉
                $send_info = '当前时间段采集的文章数量： ' . count($insert_data) . '篇';
                foreach ($insert_data as $value) {
                    if (!empty(trim($value['title']))) {
                        $send_info .= PHP_EOL . trim($value['title']);
                    }
                }
                DingService::getInstance()->textMsgSend($send_info);
            } catch (Exception $e) {
                return return_error_msg($e->getMessage());
            }

        }
        //todo 记录写入日志
        return $data_len;
    }

    /** +---------------------------------------------------------+
     *  文章采集-对应各网站采集方法
     * var collect_36kr
     *  +---------------------------------------------------------+
     */

    /**
     * 36氪
     * @param int $type
     * @return bool
     */
    public function collect_36kr($type = 1)
    {
        $time     = Carbon::now()->toDateString();
        $site_url = config('collect.url_36kr');
        $url      = $site_url . '/hot-list/renqi/' . $time . '/1';

        $reg = [
            //采集文章标题
            'title' => ['.title-wrapper', 'text'],
            'href'  => ['.title-wrapper>a', 'href'],
        ];

        $rang = '.article-list .article-wrapper';
        $data = $this->collect($url, $reg, $rang);

        $this->collect_redis_set($data, $site_url, $type);
        return true;
    }

    /**
     * 虎嗅
     * @param int $type
     * @return bool
     */
    public function collect_huxiu($type = 2)
    {
        $site_url = config('collect.url_huxiu');
        $url      = [
            $site_url . '/channel/106.html',
            $site_url . '/channel/103.html',
            $site_url . '/channel/105.html',
            $site_url . '/channel/115.html',
            $site_url . '/article/',
        ];

        foreach ($url as $v) {
            $reg  = [
                //采集文章标题
                'title' => ['h5', 'text'],
                'href'  => ['a', 'href'],
            ];
            $rang = '.channel-items .article-item';
            $data = $this->collect($v, $reg, $rang);
            $this->collect_redis_set($data, $site_url, $type);
        }

        return true;
    }

    /**
     * @param int $type
     * @return bool
     */
    public function collect_tmtpost($type = 3)
    {
        $site_url = config('collect.url_tmtpost');
        $url      = $site_url;

        $reg  = [
            //采集文章标题
            'title' => ['a', 'text'],
            'href'  => ['a', 'href'],
        ];
        $rang = '.excellent_list .info';
        $data = $this->collect($url, $reg, $rang);
        $this->collect_redis_set($data, $site_url, $type);

        return true;
    }


    public function get_test()
    {
        return $this->get_url('https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzIxNzYxMTU0OQ==&scene=124&uin=&key=&devicetype=Windows+10+x64&version=6303004c&lang=zh_CN&a8scene=7&fontgear=2');

    }


}
